package com.example.tool.action;

import com.example.tool.ui.ActionsDialogWrapper;
import com.example.tool.ui.HToolIcon;
import com.example.tool.ui.TitleCA;
import com.example.tool.utils.AES;
import com.example.tool.utils.FileUtil;
import com.intellij.ide.CutProvider;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import org.jetbrains.annotations.NotNull;

import javax.swing.JComponent;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * <p>Title: ActionUtil</p>
 * Description: 读取文件信息
 * <p>CreateTime: 2022/6/28 18:53</p>
 * @author FT
 */
public class ActionUtil {
  public static String[] getInformation(Project project) {
    try {
      if (project != null) {
        String basePath = project.getBasePath();
        URL resource = new URL("file:///" + basePath + "/.idea/seeyon.txt");
        String count = FileUtil.readFilePath(resource, false);
        if (!count.equals("")) {
          String restCount = AES.decrypt("SEEYON", count);
          if (restCount.equals(count)) {
            return null;
          }
          return restCount.split("\\|");
        }
      }
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
    return null;
  }

  @SuppressWarnings("unused")
  public static void ActionW(@NotNull AnActionEvent event) {
    Presentation presentation = event.getPresentation();
    DataContext dataContext = event.getDataContext();
    CutProvider provider = getAvailableCutProvider(event);
    Project project = CommonDataKeys.PROJECT.getData(dataContext);
    if (project != null && provider != null) {
      Navigatable[] componentRef = CommonDataKeys.NAVIGATABLE_ARRAY.getData(dataContext);
      if (null != componentRef && componentRef.length > 0) {
        String[] information = ActionUtil.getInformation(project);
        if (information != null) {
          Object node = componentRef[0];
          if (node instanceof @SuppressWarnings("rawtypes")ProjectViewNode basePsiNode) {
            VirtualFile virtualFile = basePsiNode.getVirtualFile();
            String selectPath = String.valueOf(virtualFile);
            String webContent = information[2];
            String basePath = project.getBasePath();
            if (selectPath.startsWith("file://" + basePath + "/" + webContent) && virtualFile != null) {
              presentation.setVisible(project.isOpen());
              return;
            }
          }
        }
      }
    }
    presentation.setVisible(false);
  }

  public static void ActionP(@NotNull AnActionEvent event) {
    Presentation presentation = event.getPresentation();
    DataContext dataContext = event.getDataContext();
    CutProvider provider = getAvailableCutProvider(event);
    Project project = CommonDataKeys.PROJECT.getData(dataContext);
    if (project != null && provider != null) {
      Module[] modules = ModuleManager.getInstance(project).getModules();
      List<VirtualFile> sourceAll = new ArrayList<>();
      Arrays.stream(modules).forEach(module -> {
        ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
        VirtualFile[] sourceRoots = moduleRootManager.getSourceRoots();
        List<VirtualFile> virtualFiles = Arrays.asList(sourceRoots);
        sourceAll.addAll(virtualFiles);
      });
      Navigatable[] componentRef = CommonDataKeys.NAVIGATABLE_ARRAY.getData(dataContext);
      if (null != componentRef && componentRef.length > 0) {
        Object node = componentRef[0];
        if (node instanceof ProjectViewNode) {
          @SuppressWarnings("rawtypes")
          ProjectViewNode basePsiNode = (ProjectViewNode) componentRef[0];
          VirtualFile virtualFile = basePsiNode.getVirtualFile();
          String selectPath = String.valueOf(virtualFile);
          boolean rest = sourceAll.stream().anyMatch(virtualFileItem -> {
            String prefix = virtualFileItem + "/";
            if (selectPath.startsWith(prefix) && virtualFile != null) {
              String virtualFilePath = virtualFile.getPath();
              File file = new File(virtualFilePath);
              if (file.isFile()) {
                return selectPath.substring(prefix.length()).contains("/");
              } else {
                return true;
              }
            }
            return false;
          });
          presentation.setVisible(project.isOpen() && rest);
          return;
        }
      }
    }
    presentation.setVisible(false);
  }

  private static CutProvider getAvailableCutProvider(@NotNull AnActionEvent e) {
    CutProvider provider = e.getData(PlatformDataKeys.CUT_PROVIDER);
    Project project = e.getProject();
    if (project != null && DumbService.isDumb(project) && !DumbService.isDumbAware(provider)) {
      return null;
    }
    return provider;
  }

  public static void ActionOperation(@NotNull AnActionEvent e, BiConsumer<String[], List<String>> consumer, List<String> inputValues) {
    Module module = e.getData(LangDataKeys.MODULE);
    // 当前选中的文件路径
    VirtualFile virtualFile = (VirtualFile) e.getDataContext().getData(CommonDataKeys.VIRTUAL_FILE.getName());
    if (module != null && virtualFile != null) {
      // 模块中的源文件路径，即后面的路径就是包路径
      ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
      VirtualFile[] sourceRoots = moduleRootManager.getSourceRoots();
      AtomicReference<String[]> classInformation = new AtomicReference<>();
      Arrays.stream(sourceRoots).forEach(resourceFilePath -> {
        if (virtualFile.getPath().startsWith(resourceFilePath.getPath() + "/")) {
          String virtualFilePath = virtualFile.getPath();
          File file = new File(virtualFilePath);
          String substring = null;
          String rest;
          String[] information = new String[2];
          if (file.isFile()) {
            substring = virtualFilePath.substring(0, virtualFilePath.lastIndexOf("/"));
          }
          if (substring == null) {
            information[0] = virtualFilePath;
            rest = virtualFilePath.substring(virtualFilePath.indexOf(resourceFilePath.getPath()) + resourceFilePath.getPath().length() + 1);
          } else {
            information[0] = substring;
            rest = substring.substring(substring.indexOf(resourceFilePath.getPath()) + resourceFilePath.getPath().length() + 1);
          }
          // 当前包路径
          information[1] = rest.replace("/", ".");
          classInformation.set(information);
        }
      });
      if (classInformation.get() != null) {
        // Sources目录中
        consumer.accept(classInformation.get(), inputValues);
      } else {
        //　只提供当前选中的路径
        consumer.accept(new String[]{virtualFile.getPath()}, inputValues);
      }
    } else {
      Messages.showMessageDialog(
          e.getProject(),
          "Current module is empty or this file is null",
          "Error",
          HToolIcon.ModuleIcon);
    }
  }


  public static void ActionCreatInput(@NotNull AnActionEvent e, Function<List<JComponent>, Boolean> function, BiConsumer<String[], List<String>> consumer, String... titles) {
    Project project = e.getProject();
    if (project != null) {
      ActionsDialogWrapper actionsDialogWrapper = new ActionsDialogWrapper(function, project, titles);
      if (titles.length != 0) {
        // 按下ok按键
        if (actionsDialogWrapper.showAndGet()) {
          List<String> value = actionsDialogWrapper.getValue();
          ActionOperation(e, consumer, value);
        }
      }
    } else {
      Messages.showMessageDialog(
          e.getProject(),
          "Current project is empty!",
          "Error",
          HToolIcon.ModuleIcon);
    }
  }

  public static void ActionCreatInput(@NotNull AnActionEvent e, Function<List<JComponent>, Boolean> function, BiConsumer<String[], List<String>> consumer, List<TitleCA> titleCAList) {
    Project project = e.getProject();
    if (project != null) {
      ActionsDialogWrapper actionsDialogWrapper = new ActionsDialogWrapper(function, project, titleCAList);
      if (titleCAList.size() != 0) {
        // 按下ok按键
        if (actionsDialogWrapper.showAndGet()) {
          List<String> value = actionsDialogWrapper.getValue();
          ActionOperation(e, consumer, value);
        }
      }
    } else {
      Messages.showMessageDialog(
          e.getProject(),
          "Current project is empty!",
          "Error",
          HToolIcon.ModuleIcon);
    }
  }

  @SuppressWarnings("All")
  public static void ActionCreatInput(@NotNull AnActionEvent e, BiConsumer<String[], List<String>> consumer, List<TitleCA> titleCAList) {
    Project project = e.getProject();
    if (project != null) {
      ActionsDialogWrapper actionsDialogWrapper = new ActionsDialogWrapper(project, titleCAList);
      // 按下ok按键
      if (actionsDialogWrapper.showAndGet()) {
        List<String> value = actionsDialogWrapper.getValue();
        ActionOperation(e, consumer, value);
      }
    } else {
      Messages.showMessageDialog(
          e.getProject(),
          "Current project is empty!",
          "Error",
          HToolIcon.ModuleIcon);
    }
  }

  @SuppressWarnings("All")
  public static void ActionCreatInput(@NotNull AnActionEvent e, BiConsumer<String[], List<String>> consumer, String... titles) {
    Project project = e.getProject();
    if (project != null) {
      ActionsDialogWrapper actionsDialogWrapper = new ActionsDialogWrapper(project, titles);
      // 按下ok按键
      if (actionsDialogWrapper.showAndGet()) {
        List<String> value = actionsDialogWrapper.getValue();
        ActionOperation(e, consumer, value);
      }
    } else {
      Messages.showMessageDialog(
          e.getProject(),
          "Current project is empty!",
          "Error",
          HToolIcon.ModuleIcon);
    }
  }

  // 是针对创建Controller类的Bean配置文件
  // classNames 中两个一组，先是ClassName 然后是ClassBean
  public static String appendNewControllerBean(String str, String filePath, String[] information, String[] classNames) {
    String generalBean = FileUtil.getXmlBase();
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < classNames.length; i++) {
      stringBuilder.append(generalBean.replace("$ClassName$", classNames[i + 1])
          .replace("$ClassPath$", information[1] + "." + classNames[i])).append("\n");
      i++;
    }
    stringBuilder.setLength(stringBuilder.length() - 1);
    return getString(str, filePath, stringBuilder);
  }

  public static String appendNewBean(String str, String xml, String filePath) {
    String generalBean = FileUtil.getXml(xml, true);
    return copy(str, filePath, generalBean);
  }

  public static String appendNewBean(String str, String filePath, String[] information, String... classNames) {
    String generalBean = FileUtil.getXmlBase();
    return template(str, filePath, information, generalBean, classNames);
  }

  public static String appendNewBean(String str, String xml, String filePath, String[] information, String... classNames) {
    String generalBean = FileUtil.getXml(xml, true);
    return template(str, filePath, information, generalBean, classNames);
  }

  public static String appendNewBean(String str, String xml, boolean isLineFeed, String filePath, String[] information, String... classNames) {
    String generalBean = FileUtil.getXml(xml, isLineFeed);
    return template(str, filePath, information, generalBean, classNames);
  }

  private static String copy(String str, String filePath, String generalBean) {
    StringBuilder stringBuilder = new StringBuilder(generalBean);
    return getString(str, filePath, stringBuilder);
  }

  @NotNull
  private static String template(String str, String filePath, String[] information, String generalBean, String[] classNames) {
    StringBuilder stringBuilder = new StringBuilder();
    for (String className : classNames) {
      stringBuilder.append(generalBean.replace("$ClassName$", FileUtil.lowerFirstCase(className))
          .replace("$ClassPath$", information[1] + "." + className)).append("\n");
    }
    stringBuilder.setLength(stringBuilder.length() - 1);
    return getString(str, filePath, stringBuilder);
  }

  @NotNull
  private static String getString(String str, String filePath, StringBuilder stringBuilder) {
    if (FileUtil.isHave(filePath)) {
      return str.replace("$bean$", stringBuilder);
    } else {
      try {
        URL resource = new URL("file:///" + filePath);
        String readFile = FileUtil.readFilePath(resource, true);
        return readFile.replace("</beans>", stringBuilder + "\n</beans>");
      } catch (MalformedURLException ex) {
        return str.replace("$bean$", stringBuilder);
      }
    }
  }
}
